home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / libc / Net_InetHdrChecksum.c < prev    next >
C/C++ Source or Header  |  1990-01-24  |  3KB  |  150 lines

  1. /* 
  2.  * Net_InetChecksum2.c --
  3.  *
  4.  *    Compute an internet checksum, including the header.
  5.  *
  6.  * Copyright 1987 Regents of the University of California
  7.  * All rights reserved.
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software and its documentation for any purpose and without
  10.  * fee is hereby granted, provided that the above copyright
  11.  * notice appear in all copies.  The University of California
  12.  * makes no representations about the suitability of this
  13.  * software for any purpose.  It is provided "as is" without
  14.  * express or implied warranty.
  15.  */
  16.  
  17. #ifndef lint
  18. static char rcsid[] = "$Header: /sprite/src/lib/net/RCS/Net_InetHdrChecksum.c,v 1.4 90/01/24 11:53:42 jhh Exp $ SPRITE (Berkeley)";
  19. #endif not lint
  20.  
  21.  
  22. #include "sprite.h"
  23. #include "net.h"
  24.  
  25. /*
  26.  *----------------------------------------------------------------------
  27.  *
  28.  * Net_InetChecksum2 --
  29.  *
  30.  *    This routine is an optimization for calculating checksums for
  31.  *    the UDP and TCP output routines. It is similar to Net_InetChecksum 
  32.  *    except the checksum includes the IP pseudo-header.
  33.  *
  34.  *    The comments of Net_InetChecksum apply here.
  35.  *
  36.  * Results:
  37.  *    The 1's complement checksum in network byte-order.
  38.  *
  39.  * Side effects:
  40.  *    None.
  41.  *
  42.  *----------------------------------------------------------------------
  43.  */
  44.  
  45. unsigned short
  46. Net_InetChecksum2(len, bufPtr, pseudoHdrPtr)
  47.     register int     len;        /* The # of bytes in bufPer. */
  48.     Address        bufPtr;        /* Data to checksum. */
  49.     Net_IPPseudoHdr    *pseudoHdrPtr;    /* IP pseudo-header to include in the
  50.                      * checksum. */
  51. {
  52.     register unsigned short *wordPtr;
  53.     register unsigned int sum = 0;
  54.  
  55.  
  56.     /*
  57.      * First compute the checksum for the IP pseudo-header.
  58.      */
  59.     wordPtr = (unsigned short *) pseudoHdrPtr;
  60.     if (sizeof(*pseudoHdrPtr) == 20) {
  61.     /*
  62.      * This is a hack because cpp can't use the sizeof operator 
  63.      * in #if statements.
  64.      */
  65.     sum += *wordPtr++;
  66.     sum += *wordPtr++;
  67.     sum += *wordPtr++;
  68.     sum += *wordPtr++;
  69.     sum += *wordPtr++;
  70.  
  71.     sum += *wordPtr++;
  72.     sum += *wordPtr++;
  73.     sum += *wordPtr++;
  74.     sum += *wordPtr++;
  75.     sum += *wordPtr++;
  76.  
  77.     } else {
  78.     register int i;
  79.  
  80.     i = sizeof(*pseudoHdrPtr)/sizeof(unsigned short);
  81.     do {
  82.         sum += *wordPtr++;
  83.         i--;
  84.     } while (i > 0);
  85.     }
  86.  
  87.     /*
  88.      * Sum the data in an unrolled loop. Once we have less than 
  89.      * 32 bytes to sum then it must be done in smaller loops.
  90.      */
  91.  
  92.     wordPtr = (unsigned short *) bufPtr;
  93.     while (len >= 32) {
  94.     sum += *wordPtr++;
  95.     sum += *wordPtr++;
  96.     sum += *wordPtr++;
  97.     sum += *wordPtr++;
  98.  
  99.     sum += *wordPtr++;
  100.     sum += *wordPtr++;
  101.     sum += *wordPtr++;
  102.     sum += *wordPtr++;
  103.  
  104.     sum += *wordPtr++;
  105.     sum += *wordPtr++;
  106.     sum += *wordPtr++;
  107.     sum += *wordPtr++;
  108.  
  109.     sum += *wordPtr++;
  110.     sum += *wordPtr++;
  111.     sum += *wordPtr++;
  112.     sum += *wordPtr++;
  113.  
  114.     len -= 32;
  115.     }
  116.     while (len >= 2) {
  117.     sum += *wordPtr++;
  118.     len -= 2;
  119.     }
  120.  
  121.     if (len == 1) {
  122. #if BYTE_ORDER == LITTLE_ENDIAN
  123.     sum += (*wordPtr) & 0x00ff;
  124. #else
  125.     sum += (*wordPtr) & 0xff00;
  126. #endif
  127.     }
  128.  
  129.     /*
  130.      * The most signficant bits of "sum" contains the carries from
  131.      * the overflow of the summing. Add this overflow back into
  132.      * the least significant 16 bits of the sum and do it a second
  133.      * time in case there's a carry from the first time.
  134.      */
  135.     if (sum > 0xffff) {
  136.     sum = ((sum >> 16) & 0xffff) + (sum & 0xffff);
  137.  
  138.     /*
  139.      * See if there was a carry from the addition. The overflow will
  140.      * be at most 1.
  141.      */
  142.     if (sum > 0xffff) {
  143.         sum++;
  144.     }
  145.     }
  146.  
  147.     return((~sum & 0xffff));
  148. }
  149.  
  150.